﻿#region Using Directives

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    using Csla;
    using Csla.Core;

#endregion

namespace MarketPulse.BusinessLogic.Private.BusinessRules
{

    /// <summary>
    /// Business Rule that enforces the condition end date > start date
    /// </summary>
    public class EndDateGTStartDate : Csla.Rules.BusinessRule
    {
        internal EndDateGTStartDate(IPropertyInfo primaryProperty, IPropertyInfo endDateTime) : base(primaryProperty)
        {
            InputProperties = new List<IPropertyInfo>(2) { primaryProperty, endDateTime };
        }

        /// <summary>
        /// Execute the rule
        /// </summary>
        /// <param name="context">The contextual data for executing the rule</param>
        protected override void Execute(Csla.Rules.RuleContext context)
        {
            SmartDate startDateTime = (SmartDate)context.InputPropertyValues[PrimaryProperty];
            SmartDate endDateTime = (SmartDate)context.InputPropertyValues[InputProperties[1]];
            if (endDateTime.IsEmpty)
            {
                return;
            }
            if (startDateTime.Date.CompareTo(endDateTime.Date) > 0)
            {
                context.AddErrorResult("Start date can't be after end date");
            }
        }
    }

    /// <summary>
    /// Business Rule that enforces the condition end date > start date
    /// </summary>
    public class StartDateLTEndDate : Csla.Rules.BusinessRule
    {
        internal StartDateLTEndDate(IPropertyInfo primaryProperty, IPropertyInfo startDateTime) : base(primaryProperty)
        {
            InputProperties = new List<IPropertyInfo>(2) { primaryProperty, startDateTime };
        }

        /// <summary>
        /// Execute the rule
        /// </summary>
        /// <param name="context">The contextual data for executing the rule</param>
        protected override void Execute(Csla.Rules.RuleContext context)
        {
            SmartDate endDateTime = (SmartDate)context.InputPropertyValues[PrimaryProperty];
            SmartDate startDateTime = (SmartDate)context.InputPropertyValues[InputProperties[1]];
            if (startDateTime.IsEmpty)
            {
                return;
            }
            if (endDateTime > startDateTime)
            {
                context.AddErrorResult("Start date can't be after end date");
            }
        }
    }

    
    /// <summary>
    /// Business Rule that computes the derived 'lag' date time for 
    /// latest data entry and sets the IsDataEntryPermitted 
    /// property accordingly.
    /// </summary>
    public class DerivedLatestDataEntry : Csla.Rules.BusinessRule
    {
        internal DerivedLatestDataEntry(IPropertyInfo primaryProperty, IPropertyInfo lagProperty, IPropertyInfo latestDataEntryDateTimeProperty, IPropertyInfo isDataEntryPermittedProperty) : base(primaryProperty)
        {
            InputProperties = new List<IPropertyInfo>(4) { primaryProperty, lagProperty, latestDataEntryDateTimeProperty, isDataEntryPermittedProperty };
        }

        /// <summary>
        /// Execute the rule
        /// </summary>
        /// <param name="context">The contextual data for executing the rule</param>
        protected override void Execute(Csla.Rules.RuleContext context)
        {
            SmartDate plannedEndDateTime = (SmartDate)context.InputPropertyValues[PrimaryProperty];
            TimeSpan lagTimeSpan = (TimeSpan)context.InputPropertyValues[InputProperties[1]];
            
            if (plannedEndDateTime.IsEmpty)
            {
                return;
            }
            SmartDate latestDataEntryDateTime = new SmartDate(plannedEndDateTime.Date + lagTimeSpan);
            context.AddOutValue(InputProperties[2], latestDataEntryDateTime);
            context.AddOutValue(InputProperties[3], DateTime.Now <= latestDataEntryDateTime.Date);
        }
    }


}
